package org.yunai.swjg.server.module.item;

import org.springframework.stereotype.Service;
import org.yunai.swjg.server.core.constants.SysMessageConstants;
import org.yunai.swjg.server.core.service.Online;
import org.yunai.swjg.server.module.item.container.Bag;
import org.yunai.swjg.server.module.item.container.CommonBag;
import org.yunai.swjg.server.module.item.container.EquipmentBag;
import org.yunai.swjg.server.module.item.container.ShoulderBag;
import org.yunai.swjg.server.module.item.template.ItemTemplate;
import org.yunai.swjg.server.module.item.vo.Item;
import org.yunai.swjg.server.module.player.vo.Player;
import org.yunai.swjg.server.rpc.message.S_C.S_C_SysMessageReq;
import org.yunai.yfserver.util.Assert;

import java.util.ArrayList;
import java.util.List;

/**
 * 道具Service
 * User: yunai
 * Date: 13-4-11
 * Time: 下午10:50
 */
@Service
public class ItemService {

    /**
     * 添加道具<br />
     * TODO 该方法用于测试用，实际需要修改
     *
     * @param online     在线信息
     * @param templateId 道具模版编号
     * @param count      道具数量
     */
    public void addItemToPrimBag(Online online, Integer templateId, Integer count) {
        ItemTemplate template = ItemTemplate.getItemTemplate(templateId);
        Assert.notNull(template, "templateId:" + templateId + "不存在！");

        ShoulderBag primBag = online.getPlayer().getInventory().getPrimBag();
        List<Item> updateItems = primBag.add(template, count);
        if (!updateItems.isEmpty()) {
            online.write(BagMessageBuilder.build(updateItems));
        }
    }

    /**
     * 丢弃道具<br />
     * 只允许主背包({@link org.yunai.swjg.server.module.item.container.Bag.BagType#PRIM}丢弃
     *
     * @param online 在线信息
     * @param bagId  背包标号
     * @param index  背包位置
     */
    public void dropItem(Online online, byte bagId, int index) {
        Bag.BagType bagType = Bag.BagType.valueOf(bagId);
        if (Bag.BagType.isNullBag(bagType)) {
            return;
        }
        CommonBag bag = online.getPlayer().getInventory().getBag(bagType);
        if (bag == null) {
            return;
        }

        Item updateItem;
        switch (bagType) {
            case PRIM:
                updateItem = bag.drop(index);
                break;
            default:
                throw new RuntimeException("error bag");
        }
        if (updateItem != null) {
            BagMessageBuilder.build(updateItem);
        }
    }

    /**
     * 背包整理<br />
     * 允许整理的背包有：
     * <pre>
     *     1. 主背包({@link org.yunai.swjg.server.module.item.container.Bag.BagType#PRIM}
     *     2. 仓库背包({@link org.yunai.swjg.server.module.item.container.Bag.BagType#DEPOT}
     * </pre>
     *
     * @param online 在线信息
     * @param bagId  背包编号
     */
    public void packUpBag(Online online, byte bagId) {
        Bag.BagType bagType = Bag.BagType.valueOf(bagId);
        if (Bag.BagType.isNullBag(bagType)) {
            return;
        }
        CommonBag bag = online.getPlayer().getInventory().getBag(bagType);
        if (bag == null) {
            return;
        }

        switch (bagType) {
            case PRIM:
            case DEPOT:
                bag.packUp();
                break;
            default:
                throw new RuntimeException("error bag packUp");
        }

        List<Item> items = bag.getAll();
        if (!items.isEmpty()) {
            online.write(BagMessageBuilder.build(items));
        }
    }

    /**
     * 移动道具<br />
     * 该操作是两个位置上的道具位置兑换。<br />
     * TODO 暂时不支持A道具移动另外A道具的位置之后合并成一个位置。
     *
     * @param online    在线信息
     * @param fromBagId 移动道具所在背包编号
     * @param index     移动道具所在背包位置
     * @param toBagId   目标背包编号
     * @param toIndex   目标背包位置
     */
    public void moveItem(Online online, byte fromBagId, int index, byte toBagId, int toIndex) {
        // 检查
        Bag.BagType fromBagType = Bag.BagType.valueOf(fromBagId);
        if (Bag.BagType.isNullBag(fromBagType)) {
            return;
        }
        Bag.BagType toBagType = Bag.BagType.valueOf(toBagId);
        if (Bag.BagType.isNullBag(toBagType)) {
            return;
        }
        Inventory inventory = online.getPlayer().getInventory();
        CommonBag fromBag = inventory.getBag(fromBagType);
        if (fromBag == null) {
            return;
        }
        Item item = fromBag.getByIndex(index);
        if (item == null) {
            return;
        }
        CommonBag toBag = inventory.getBag(toBagType);
        if (toBag == null) {
            return;
        }

        // 逻辑真正开始
        boolean success = toBag.move(item, toBag, toIndex);
        if (success) {
            online.write(BagMessageBuilder.build(item));
        }
    }

    /**
     * 穿戴装备<br />
     * 只有主背包的装备才能穿戴
     *
     * @param online 在线信息
     * @param index  指定装备的背包位置
     */
    public void equip(Online online, Integer index) {
        // 验证
        Inventory inventory = online.getPlayer().getInventory();
        ShoulderBag primBag = inventory.getPrimBag();
        Item equipment = primBag.getByIndex(index);
        if (equipment == null || !equipment.isEquipment()) {
            return;
        }
        // 穿戴
        List<Item> changedItems = new ArrayList<>(2);
//        EquipmentBag equipmentBag = inventory.getPlayerEquipBag(); // TODO 需要赶紧改
        EquipmentBag equipmentBag = null;
        Item curEquipment = equipmentBag.getEquipment(equipment.getType());
        if (curEquipment != null) { // 卸下原来穿戴的装备
            curEquipment.changeOwner(Item.OWNER_ID_NONE);
            equipment.changeOwner(online.getPlayer().getId());
            inventory.swap(equipment, curEquipment);
            changedItems.add(curEquipment);
            changedItems.add(equipment);
        } else {
            equipment.changeOwner(online.getPlayer().getId());
            primBag.move(equipment, equipmentBag, equipmentBag.getPosition(equipment.getType()));
            changedItems.add(equipment);
        }
        // 重新计算人物属性
        online.getPlayer().calcRoleProps(true);
        // 发送消息给客户端
        online.write(BagMessageBuilder.build(changedItems)); // 背包改变
    }

    /**
     * 卸下装备到主背包
     *
     * @param online 在线信息
     * @param type   装备类型
     */
    public void unEquip(Online online, Integer type) {
        // 验证
        Inventory inventory = online.getPlayer().getInventory();
//        EquipmentBag equipmentBag = inventory.getPlayerEquipBag();
        EquipmentBag equipmentBag = null;
        ItemDef.Type itemDefType = ItemDef.Type.valueOf(type);
        if (itemDefType == null || !itemDefType.isEquipment()) {
            return;
        }
        Item equipment = equipmentBag.getEquipment(itemDefType);
        if (equipment == null) {
            return;
        }
        // 卸下
        ShoulderBag primBag = inventory.getPrimBag();
        if (!equipmentBag.move(equipment, primBag)) { // 背包已满
            online.write(new S_C_SysMessageReq(SysMessageConstants.BAG_PRIM__FULL));
            return;
        }
        equipment.changeOwner(Item.OWNER_ID_NONE);
        // 重新计算人物属性
        online.getPlayer().calcRoleProps(true);
        // 发送消息给客户端
        online.write(BagMessageBuilder.build(equipment)); // 背包改变
    }

    public void useItem(Online online, byte bagId, int bagIndex, int ownerId, int targetId, int param) {
        Bag.BagType bagType = Bag.BagType.valueOf(bagId);
        Player player = online.getPlayer();
        if (Bag.BagType.isNullBag(bagType)) {
            player.message(new S_C_SysMessageReq(SysMessageConstants.ITEM_BAG_TYPE_ERROR));
            return;
        }
        Inventory inventory = player.getInventory();
        Item item;
        switch (bagType) {
            case PRIM:
                item = inventory.getItem(player.getId(), bagType, bagIndex);
                break;
            case EQUIPMENT:
                item = inventory.getItem(ownerId, bagType, bagIndex);
                break;
            default:
                player.message(new S_C_SysMessageReq(SysMessageConstants.ITEM_NOT_FOUND));
                return;
        }
        item.use(targetId, param);
    }
}